package lancoo.com.net.retrofitrxjava.download;


import android.text.TextUtils;

import androidx.lifecycle.LifecycleOwner;

import com.rxjava.rxlife.RxLife;

import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import lancoo.com.net.retrofitrxjava.NetworkTransformer;
import lancoo.com.net.retrofitrxjava.network.Network;
import okhttp3.MultipartBody;
import okhttp3.ResponseBody;

/**
 * Retrofit的主要调用函数
 */

public class HttpDownManager {
    private static HttpDownManager mInstance;
    private static String mBaseUrl;

    private HttpDownManager() {
    }

    /**
     * 获取Retrofit的实例
     *
     * @return
     */
    public static HttpDownManager getInstance() {
        if (mInstance == null) {
            mInstance=new HttpDownManager();
        }
        return mInstance;
    }

    /**
     * 构建请求
     *
     * @param clz 请求接口
     * @param <T>
     * @return
     */
    public <T> T create(Class<T> clz) {
        return Network.getJsonData1(clz);
    }


    /**
     * 单上传文件的封装
     *
     * @param url                完整的接口地址
     * @param file               需要上传的文件
     * @param fileUploadObserver 上传监听回调
     */
    public Disposable upLoadFile(String url, File file, final FileUploadObserver<ResponseBody> fileUploadObserver) {
        UploadFileRequestBody<ResponseBody> uploadFileRequestBody = new UploadFileRequestBody<>(file, fileUploadObserver);
        MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), uploadFileRequestBody);
        return create(BASE_API.class)
                .uploadFile(url, part)
                .compose(NetworkTransformer.<ResponseBody>commonSchedulers())
                .subscribe(new Consumer<ResponseBody>() {
                    @Override
                    public void accept(@NonNull ResponseBody responseBody) throws Exception {
                        fileUploadObserver.onUpLoadSuccess(responseBody);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(@NonNull Throwable throwable) throws Exception {
                        fileUploadObserver.onUpLoadFail(throwable);
                    }
                }, new Action() {
                    @Override
                    public void run() throws Exception {
                        fileUploadObserver.onComplete();
                    }
                });
    }


    /**
     * 下载单文件，可以是大文件，该方法不支持断点下载
     * @param url                  文件地址
     * @param destDir              存储文件夹
     * @param fileName             存储文件名
     * @param fileDownLoadObserver 监听回调
     */
    public Disposable downloadFile(@NonNull String url, final String destDir, final String fileName,
                                   final FileDownLoadObserver<File> fileDownLoadObserver,LifecycleOwner owner) {
        File file=new File(destDir,fileName);
        if(file.exists()){
            file.delete();
        }
        return create(BASE_API.class)
                .downLoadFile(url)
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .observeOn(Schedulers.computation())
                .map(new Function<ResponseBody, File>() {
                    @Override
                    public File apply(@NonNull ResponseBody responseBody) throws Exception {
                        return fileDownLoadObserver.saveFile(responseBody, destDir, fileName);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .as(RxLife.as(owner))
                .subscribe(new Consumer<File>() {
                    @Override
                    public void accept(@NonNull File file) throws Exception {
                        fileDownLoadObserver.onDownLoadSuccess(file);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(@NonNull Throwable throwable) throws Exception {
                        fileDownLoadObserver.onDownLoadFail(throwable);
                    }
                }, new Action() {
                    @Override
                    public void run() throws Exception {
                        fileDownLoadObserver.onComplete();
                    }
                });
    }




}
